﻿using System.Text;
using System.Text.RegularExpressions;
using Spectre.Console;

namespace gpt;
public static class MarkdownToSpectreConverter
{
    #region 正则表达式（静态常量）
    // 标题：支持 # 至 ###### 及不规范空格
    private static readonly Regex HeaderRegex = new Regex(
        @"^[ \t]*(#{1,6})(?!\S)[ \t]*(.+?)[ \t]*(#*)[ \t]*$",
        RegexOptions.Multiline | RegexOptions.IgnoreCase
    );

    // 水平线：--- 或 ***
    private static readonly Regex HorizontalRuleRegex = new Regex(
        @"^[-*]{3,}$",
        RegexOptions.Multiline
    );

    // 无序列表：- / * / +
    private static readonly Regex UnorderedListRegex = new Regex(
        @"^\s*[-*+]\s+(.+)$",
        RegexOptions.Multiline
    );

    // 有序列表：1. / 2. 等
    private static readonly Regex OrderedListRegex = new Regex(
        @"^\s*\d+\.\s+(.+)$",
        RegexOptions.Multiline
    );

    // 代码块：```code```
    private static readonly Regex CodeBlockRegex = new Regex(
        @"```.*?\r?\n(.+?)```",
        RegexOptions.Singleline
    );

    // 链接：[text](url)
    private static readonly Regex LinkRegex = new Regex(
        @"\[([^]]+)\]\(([^)]+)\)",
        RegexOptions.None
    );

    // 图片：![alt](src)
    private static readonly Regex ImageRegex = new Regex(
        @"!\[([^]]+)\]\(([^)]+)\)",
        RegexOptions.None
    );

    // 粗体：**text** 或 __text__
    private static readonly Regex BoldRegex = new Regex(
        @"(\*\*|__)(.+?)\1",
        RegexOptions.None
    );

    // 斜体：*text* 或 _text_
    private static readonly Regex ItalicRegex = new Regex(
        @"(\*|_)(.+?)\1",
        RegexOptions.None
    );
    #endregion

    public static string Convert(string markdown)
    {
        if (string.IsNullOrWhiteSpace(markdown)) return markdown;
        var text = markdown;

        // 处理转义字符（优先级最高）
        text = EscapeSpectreMarkup(text);

        // 处理块级元素
        text = ProcessCodeBlocks(text);
        text = ProcessHeaders(text);
        text = ProcessHorizontalRules(text);
        text = ProcessLists(text);

        // 处理行内元素
        text = ProcessBoldAndItalic(text);
        text = ProcessLinks(text);
        text = ProcessImages(text);

        return text;
    }

    #region 处理方法
    private static string EscapeSpectreMarkup(string text)
    {
        return text.Replace("[", "[[").Replace("]", "]]");
    }

    private static string ProcessHeaders(string text)
    {
        return HeaderRegex.Replace(text, match =>
        {
            int level = match.Groups[1].Value.Length;
            string content = match.Groups[2].Value.Trim();

            if (match.Groups[3].Success)
            {
                content = content.Replace(match.Groups[3].Value, "").Trim();
            }

            return level switch
            {
                1 => $"[bold yellow]{content}[/]\n{new string('═', content.Length + 2)}",
                2 => $"[bold cyan]{content}[/]\n{new string('─', content.Length + 2)}",
                _ => $"[bold]{new string('#', level)} {content}[/]"
            };
        });
    }

    private static string ProcessHorizontalRules(string text)
    {
        return HorizontalRuleRegex.Replace(text,
            _ => new string('-',  80));
    }

    private static string ProcessLists(string text)
    {
        text = UnorderedListRegex.Replace(text, "• $1");
        text = OrderedListRegex.Replace(text, "$1");
        return text;
    }

    private static string ProcessCodeBlocks(string text)
    {
        return CodeBlockRegex.Replace(text, match =>
            $"\n[grey on black]{EscapeMarkup(match.Groups[1].Value)}[/]\n");
    }

    private static string ProcessBoldAndItalic(string text)
    {
        text = ProcessNestedMarkup(text, BoldRegex, "bold");
        text = ProcessNestedMarkup(text, ItalicRegex, "italic");
        return text;
    }

    private static string ProcessLinks(string text)
    {
        return LinkRegex.Replace(text, "[link=$2]$1[/]");
    }

    private static string ProcessImages(string text)
    {
        return ImageRegex.Replace(text, "[grey](图片: $1)[/]");
    }

    private static string ProcessNestedMarkup(string text, Regex regex, string style)
    {
        while (regex.IsMatch(text))
        {
            text = regex.Replace(text, $"[{style}]$2[/]");
        }
        return text;
    }
    #endregion

    private static string EscapeMarkup(this string text)
    {
        return text.Replace("[", "[[").Replace("]", "]]");
    }
}